home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / KPlib 1.3.5 / KPList.h < prev    next >
Text File  |  1995-12-17  |  49KB  |  1,645 lines

  1. // A module of KPlib v1.3.5.
  2. // Written by Keith Pomakis during the summer of 1994.
  3. // Released to the public domain on October 10, 1994.
  4.  
  5. #ifndef KP_LIST_DEFINED
  6. #define KP_LIST_DEFINED
  7.  
  8. #include <iostream.h>
  9. #include <stdlib.h>
  10. #include "KPbasic.h"
  11.  
  12. // To insure that KPList isn't defined before KPString, so that
  13. // KPList<KPString> will be considered a complete type in the KPString.h
  14. // header file.  This is probably a g++-specific problem.
  15. #include "KPString.h"
  16.  
  17. // Assumes Element has a default constructor and operator=().
  18.  
  19. template <class Element>
  20. class KPList {
  21.         friend class KPReadOnlyIterator<Element>;
  22.         friend class KPIterator<Element>;
  23.     public:
  24.         KPList();
  25.         KPList(const KPList<Element> &list);
  26.         KPList(const Element &element);
  27.         virtual ~KPList();
  28.         KPList<Element> operator+(const KPList<Element> &list);
  29.         KPList<Element> operator+(const Element &element);
  30.         void operator+=(const KPList<Element> &list);
  31.         void operator+=(const Element &element);
  32.         KPList<Element> &operator=(const KPList<Element> &list);
  33.         KPList<Element> &operator=(const Element &element);
  34.         Element &head();
  35.         Element &tail();
  36.         const Element &head() const;
  37.         const Element &tail() const;
  38.         void add_to_head(const Element &element);
  39.         void add_to_tail(const Element &element);
  40.         void remove_head();
  41.         void remove_tail();
  42.         Element &operator[](int index);
  43.         const Element &operator[](int index) const;
  44.         int size() const;
  45.         bool is_empty() const;
  46.         void clear();
  47.         KPList<Element> all_such_that(bool (*f)(const Element &)) const;
  48.  
  49.     protected:
  50.         struct Node {
  51.             Element element;
  52.             Node *previous;
  53.             Node *next;
  54.         };
  55.         static void error(const char *msg);
  56.         int my_size;
  57.         unsigned int my_iterator_count;
  58.         Node *my_head;
  59.         Node *my_tail;
  60. };
  61.  
  62. // Assumes Element has the above plus operator==().
  63.  
  64. template <class Element>
  65. class KPComparableList: public KPList<Element> {
  66.     public:
  67.         KPComparableList();
  68.         KPComparableList(const KPComparableList<Element> &list);
  69.         KPComparableList(const KPList<Element> &list);
  70.         KPComparableList(const Element &element);
  71.         virtual ~KPComparableList();
  72.         KPComparableList<Element> &operator=(const KPList<Element> &list);
  73.         KPComparableList<Element> &operator=(const Element &element);
  74.         KPComparableList<Element> operator+(const KPList<Element> &list);
  75.         KPComparableList<Element> operator+(const Element &element);
  76.         KPComparableList<Element>
  77.                             operator-(const KPComparableList<Element> &list);
  78.         KPComparableList<Element> operator-(const Element &element);
  79.         void operator-=(const KPComparableList<Element> &list);
  80.         void operator-=(const Element &element);
  81.         bool operator==(const KPComparableList<Element> &list) const;
  82.         bool operator!=(const KPComparableList<Element> &list) const;
  83.         bool contains(const KPComparableList<Element> &list) const;
  84.         bool contains(const Element &element) const;
  85.         int occurrences_of(const Element &element) const;
  86.         void clear();
  87.         void clear(const Element &element);
  88.         void clear(const KPComparableList<Element> &list);
  89.     protected:
  90.         static void error(const char *msg);
  91. };
  92.  
  93. // Assumes Element has the above plus operator<().  Note that this operator
  94. // must place a total ordering on the set of Elements.
  95.  
  96. template <class Element>
  97. class KPSortableList: public KPComparableList<Element> {
  98.     public:
  99.         KPSortableList();
  100.         KPSortableList(const KPSortableList<Element> &list);
  101.         KPSortableList(const KPList<Element> &list);
  102.         KPSortableList(const Element &element);
  103.         virtual ~KPSortableList();
  104.         KPSortableList<Element> &operator=(const KPList<Element> &list);
  105.         KPSortableList<Element> &operator=(const Element &element);
  106.         bool operator<(const KPSortableList<Element> &list) const;
  107.         void sort();
  108.         Element &min();
  109.         const Element &min() const;
  110.         Element &max();
  111.         const Element &max() const;
  112.     protected:
  113.         static void error(const char *msg);
  114.         static int findpivot(int i, int j, Element **elementlist);
  115.         static int partition(int l, int r, const Element &pivot,
  116.                                                     Element **elementlist);
  117.         static void quicksort(int i, int j, Element **elementlist);
  118. };
  119.  
  120. // A list keeps track of the number of iterators iterating over it.  Rules:
  121. //
  122. //    - If a list has no iterators, one can add to and remove from that
  123. //      list without restriction.
  124. //
  125. //    - If a list has one iterator, one can add to and remove elements from
  126. //      the list through the iterator without restriction, although one
  127. //      cannot remove elements from the list directly.
  128. //
  129. //    - If a list has more than one iterator, one cannot remove elements
  130. //      from the list at all.
  131. //
  132. // As a result, if a list goes out of scope while there is still an
  133. // iterator attached to it, this is an error.  Usually the declaration of
  134. // an iterator appears after the declaration of the list it is to iterate
  135. // over (or it is in a more local scope), so this is usually not a problem
  136. // (since it's destructor is called first, detaching it implicitly).  To
  137. // detach an iterator from a list explicitly, call iterate_over().
  138.  
  139. // Use KPReadOnlyIterator if you wish to iterate over a const KPList or if you
  140. // do not intend to modify the list through the iterator.
  141.  
  142. template <class Element>
  143. class KPReadOnlyIterator {
  144.     public:
  145.         KPReadOnlyIterator();
  146.         KPReadOnlyIterator(const KPList<Element> &list);
  147.         KPReadOnlyIterator(const KPReadOnlyIterator<Element> &iterator);
  148.         ~KPReadOnlyIterator();
  149.         KPReadOnlyIterator<Element> &iterate_over(const KPList<Element> &list);
  150.         KPReadOnlyIterator<Element> &iterate_over();
  151.         KPReadOnlyIterator<Element> &
  152.                         operator=(const KPReadOnlyIterator<Element> &iterator);
  153.         const Element ¤t() const;
  154.         const Element *ptr() const;
  155.         KPReadOnlyIterator<Element> &beginning();
  156.         KPReadOnlyIterator<Element> &end();
  157.         KPReadOnlyIterator<Element> &operator++();  // Prefix
  158.         KPReadOnlyIterator<Element> &operator--();  // Prefix
  159.         void operator++(int);                       // Postfix
  160.         void operator--(int);                       // Postfix
  161.         const Element &operator*() const;
  162.         const Element *operator->() const;
  163.         bool at_beginning() const;
  164.         bool at_end() const;
  165.         int size() const;
  166.         bool is_empty() const;
  167.         const KPList<Element> &list() const;
  168.     protected:
  169.         static void error(const char *msg);
  170.         const KPList<Element> *my_list;
  171.         const KPList<Element>::Node *my_current;
  172. };
  173.  
  174. // The rules defining what happens when odd combinations of element
  175. // removals and insertions are performed are fairly intuitive.  An element
  176. // can be deleted while the list is being parsed, and the parse can
  177. // continue.  "Previous" and "next" retain their meanings.  Just don't try
  178. // to access an element after it has been deleted!
  179.  
  180. template <class Element>
  181. class KPIterator {
  182.     public:
  183.         KPIterator();
  184.         KPIterator(KPList<Element> &list);
  185.         KPIterator(const KPIterator<Element> &iterator);
  186.         ~KPIterator();
  187.         KPIterator<Element> &iterate_over(KPList<Element> &list);
  188.         KPIterator<Element> &iterate_over();
  189.         KPIterator<Element> &operator=(const KPIterator<Element> &iterator);
  190.         KPIterator<Element> &insert_before_current(const Element &element);
  191.         KPIterator<Element> &insert_after_current(const Element &element);
  192.         KPIterator<Element> &replace_current_with(const Element &element);
  193.         Element ¤t();
  194.         Element *ptr();
  195.         void remove_current();
  196.         KPIterator<Element> &beginning();
  197.         KPIterator<Element> &end();
  198.         KPIterator<Element> &operator++();  // Prefix
  199.         KPIterator<Element> &operator--();  // Prefix
  200.         void operator++(int);               // Postfix
  201.         void operator--(int);               // Postfix
  202.         Element &operator*();
  203.         Element *operator->();
  204.         bool at_beginning() const;
  205.         bool at_end() const;
  206.         int size() const;
  207.         bool is_empty() const;
  208.         KPList<Element> &list();
  209.     protected:
  210.         static void error(const char *msg);
  211.         KPList<Element> *my_list;
  212.         KPList<Element>::Node my_deleted;
  213.         KPList<Element>::Node *my_current;
  214. };
  215.  
  216. // The following macro is defined as a convenience.  Here is an example of
  217. // its usage:
  218. //
  219. //     KPSortableList<int> intlist;
  220. //     intlist += 42;
  221. //     intlist += 11;
  222. //     intlist += 76;
  223. //     intlist += 9;
  224. //     intlist.sort();
  225. //
  226. //     KPReadOnlyIterator<int> iter(intlist);
  227. //     FOREACH(iter) cout << *iter << '\n';
  228.  
  229. #define FOREACH(iter) for (iter.beginning(); iter.ptr(); iter++)
  230.  
  231. /****************************************************************************/
  232.  
  233. template <class Element>
  234. inline
  235. KPList<Element>::KPList()
  236. {
  237.     my_size = my_iterator_count = 0;
  238.     my_head = my_tail = NULL;
  239. }
  240.  
  241. /****************************************************************************/
  242.  
  243. template <class Element>
  244. inline
  245. KPList<Element>::KPList(const KPList<Element> &list)
  246. {
  247.     my_size = my_iterator_count = 0;
  248.     my_head = my_tail = NULL;
  249.     *this = list;
  250. }
  251.  
  252. /****************************************************************************/
  253.  
  254. template <class Element>
  255. inline
  256. KPList<Element>::KPList(const Element &element)
  257. {
  258.     my_size = my_iterator_count = 0;
  259.     my_head = my_tail = NULL;
  260.     *this = element;
  261. }
  262.  
  263. /****************************************************************************/
  264.  
  265. template <class Element>
  266. inline
  267. KPList<Element>::~KPList()
  268. {
  269.     if (my_iterator_count > 0)
  270.         error("~KPList() - cannot destroy, iterators present");
  271.  
  272.     clear();
  273. }
  274.  
  275. /****************************************************************************/
  276.  
  277. template <class Element>
  278. inline KPList<Element>
  279. KPList<Element>::operator+(const KPList<Element> &list)
  280. {
  281.     KPList<Element> new_list(*this);
  282.     new_list += list;
  283.     return new_list;
  284. }
  285.  
  286. /****************************************************************************/
  287.  
  288. template <class Element>
  289. inline KPList<Element>
  290. KPList<Element>::operator+(const Element &element)
  291. {
  292.     KPList<Element> new_list(*this);
  293.     new_list += element;
  294.     return new_list;
  295. }
  296.  
  297. /****************************************************************************/
  298.  
  299. template <class Element>
  300. void
  301. KPList<Element>::operator+=(const KPList<Element> &list)
  302. {
  303.     register const Node *node;
  304.     const int size = list.my_size;
  305.     int i;
  306.  
  307.     // Must use size as stopping condition in case *this == list.
  308.     for (node = list.my_head, i=0; i < size; node = node->next, i++)
  309.         *this += node->element;
  310. }
  311.  
  312. /****************************************************************************/
  313.  
  314. template <class Element>
  315. void
  316. KPList<Element>::operator+=(const Element &element)
  317. {
  318.     Node *newnode = new Node;
  319.     check_mem(newnode);
  320.     newnode->next = NULL;
  321.     newnode->element = element;
  322.     if (my_size++ == 0) {
  323.         my_head = newnode;
  324.         newnode->previous = NULL;
  325.     }
  326.     else {
  327.         my_tail->next = newnode;
  328.         newnode->previous = my_tail;
  329.     }
  330.     my_tail = newnode;
  331. }
  332.  
  333. /****************************************************************************/
  334.  
  335. template <class Element>
  336. KPList<Element> &
  337. KPList<Element>::operator=(const KPList<Element> &list)
  338. {
  339.     if (this == &list)
  340.         return *this;
  341.  
  342.     if (my_iterator_count > 0)
  343.         error("operator=() - cannot reassign, iterators present");
  344.  
  345.     register Node *node;
  346.     Node *newnode, *prevnode;
  347.  
  348.     clear();
  349.  
  350.     if (!(node = list.my_head))
  351.         return *this;
  352.  
  353.     newnode = new Node;
  354.     check_mem(newnode);
  355.     newnode->previous = NULL;
  356.     newnode->element = node->element;
  357.     my_head = prevnode = newnode;
  358.  
  359.     for (node = node->next; node; node = node->next) {
  360.         newnode = new Node;
  361.         check_mem(newnode);
  362.         newnode->element = node->element;
  363.         prevnode->next = newnode;
  364.         newnode->previous = prevnode;
  365.         prevnode = newnode;
  366.     }
  367.     newnode->next = NULL;
  368.     my_tail = newnode;
  369.     my_size = list.my_size;
  370.  
  371.     return *this;
  372. }
  373.  
  374. /****************************************************************************/
  375.  
  376. template <class Element>
  377. KPList<Element> &
  378. KPList<Element>::operator=(const Element &element)
  379. {
  380.     if (my_iterator_count > 0)
  381.         error("operator=() - cannot reassign, iterators present");
  382.  
  383.     clear();
  384.  
  385.     Node *newnode = new Node;
  386.     check_mem(newnode);
  387.     newnode->element = element;
  388.     newnode->previous = newnode->next = NULL;
  389.     my_head = my_tail = newnode;
  390.     my_size = 1;
  391.  
  392.     return *this;
  393. }
  394.  
  395. /****************************************************************************/
  396.  
  397. template <class Element>
  398. inline Element &
  399. KPList<Element>::head()
  400. {
  401.     if (!my_head)
  402.         error("head() - list is empty");
  403.  
  404.     return my_head->element;
  405. }
  406.  
  407. /****************************************************************************/
  408.  
  409. template <class Element>
  410. inline Element &
  411. KPList<Element>::tail()
  412. {
  413.     if (!my_tail)
  414.         error("tail() - list is empty");
  415.  
  416.     return my_tail->element;
  417. }
  418.  
  419. /****************************************************************************/
  420.  
  421. template <class Element>
  422. inline const Element &
  423. KPList<Element>::head() const
  424. {
  425.     if (!my_head)
  426.         error("head() - list is empty");
  427.  
  428.     return my_head->element;
  429. }
  430.  
  431. /****************************************************************************/
  432.  
  433. template <class Element>
  434. inline const Element &
  435. KPList<Element>::tail() const
  436. {
  437.     if (!my_tail)
  438.         error("tail() - list is empty");
  439.  
  440.     return my_tail->element;
  441. }
  442.  
  443. /****************************************************************************/
  444.  
  445. template <class Element>
  446. void
  447. KPList<Element>::add_to_head(const Element &element)
  448. {
  449.     Node *newnode = new Node;
  450.     check_mem(newnode);
  451.     newnode->element = element;
  452.     newnode->previous = NULL;
  453.     newnode->next = my_head;
  454.  
  455.     if (my_size++)
  456.         my_head->previous = newnode;
  457.     else
  458.         my_tail = newnode;
  459.     my_head = newnode;
  460. }
  461.  
  462. /****************************************************************************/
  463.  
  464. template <class Element>
  465. void
  466. KPList<Element>::add_to_tail(const Element &element)
  467. {
  468.     Node *newnode = new Node;
  469.     check_mem(newnode);
  470.     newnode->element = element;
  471.     newnode->previous = my_tail;
  472.     newnode->next = NULL;
  473.  
  474.     if (my_size++)
  475.         my_tail->next = newnode;
  476.     else
  477.         my_head = newnode;
  478.     my_tail = newnode;
  479. }
  480.  
  481. /****************************************************************************/
  482.  
  483. template <class Element>
  484. void
  485. KPList<Element>::remove_head()
  486. {
  487.     if (my_iterator_count > 0)
  488.         error("remove_head() - cannot remove element, iterators present");
  489.  
  490.     Node *old_head = my_head;
  491.     if (old_head) {
  492.         if (old_head->next) {
  493.             old_head->next->previous = NULL;
  494.             my_head = old_head->next;
  495.         }
  496.         else
  497.             my_head = my_tail = NULL;
  498.  
  499.         delete old_head;
  500.         my_size--;
  501.     }
  502. }
  503.  
  504. /****************************************************************************/
  505.  
  506. template <class Element>
  507. void
  508. KPList<Element>::remove_tail()
  509. {
  510.     if (my_iterator_count > 0)
  511.         error("remove_tail() - cannot remove element, iterators present");
  512.  
  513.     Node *old_tail = my_tail;
  514.     if (old_tail) {
  515.         if (old_tail->previous) {
  516.             old_tail->previous->next = NULL;
  517.             my_tail = old_tail->previous;
  518.         }
  519.         else
  520.             my_head = my_tail = NULL;
  521.  
  522.         delete old_tail;
  523.         my_size--;
  524.     }
  525. }
  526.  
  527. /****************************************************************************/
  528.  
  529. template <class Element>
  530. Element &
  531. KPList<Element>::operator[](int index)
  532. {
  533.     if (index < 0 || index >= my_size)
  534.         error("operator[] - invalid index");
  535.  
  536.     register Node *node = my_head;
  537.     for (register int i=0; i<index; i++)
  538.         node = node->next;
  539.  
  540.     return node->element;
  541. }
  542.  
  543. /****************************************************************************/
  544.  
  545. template <class Element>
  546. const Element &
  547. KPList<Element>::operator[](int index) const
  548. {
  549.     if (index < 0 || index >= my_size)
  550.         error("operator[] - invalid index");
  551.  
  552.     register Node *node = my_head;
  553.     for (register int i=0; i<index; i++)
  554.         node = node->next;
  555.  
  556.     return node->element;
  557. }
  558.  
  559. /****************************************************************************/
  560.  
  561. template <class Element>
  562. inline int
  563. KPList<Element>::size() const
  564. {
  565.     return my_size;
  566. }
  567.  
  568. /****************************************************************************/
  569.  
  570. template <class Element>
  571. inline bool
  572. KPList<Element>::is_empty() const
  573. {
  574.     return (my_size == 0);
  575. }
  576.  
  577. /****************************************************************************/
  578.  
  579. template <class Element>
  580. void
  581. KPList<Element>::clear()
  582. {
  583.     register Node *nextnode;
  584.  
  585.     if (my_iterator_count > 0)
  586.         error("clear() - cannot clear, iterators present");
  587.  
  588.     for (register Node *node = my_head; node; node = nextnode) {
  589.         nextnode = node->next;
  590.         delete node;
  591.     }
  592.     my_size = 0;
  593.     my_head = my_tail = NULL;
  594. }
  595.  
  596. /****************************************************************************/
  597.  
  598. template <class Element>
  599. KPList<Element>
  600. KPList<Element>::all_such_that(bool (*f)(const Element &)) const
  601. {
  602.     KPList<Element> new_list;
  603.  
  604.     for (register const Node *node = my_head; node; node = node->next)
  605.         if (f(node->element))
  606.             new_list += node->element;
  607.  
  608.     return new_list;
  609. }
  610.  
  611. /****************************************************************************/
  612.  
  613. template <class Element>
  614. void
  615. KPList<Element>::error(const char *msg)
  616. {
  617.     cerr << "KPList: " << msg << '\n';
  618.     exit(EXIT_FAILURE);
  619. }
  620.  
  621. /****************************************************************************/
  622.  
  623. template <class Element>
  624. inline KPComparableList<Element>::KPComparableList(): KPList<Element>()
  625. { /* do nothing new. */ }
  626.  
  627. /****************************************************************************/
  628.  
  629. template <class Element>
  630. inline KPComparableList<Element>::KPComparableList(
  631.                 const KPComparableList<Element> &list): KPList<Element>(list)
  632. { /* do nothing new. */ }
  633.  
  634. /****************************************************************************/
  635.  
  636. template <class Element>
  637. inline KPComparableList<Element>::KPComparableList(const KPList<Element> &list):
  638.                                                         KPList<Element>(list)
  639. { /* do nothing new. */ }
  640.  
  641. /****************************************************************************/
  642.  
  643. template <class Element>
  644. inline
  645. KPComparableList<Element>::KPComparableList(const Element &element):
  646.                                                     KPList<Element>(element)
  647. { /* do nothing new. */ }
  648.  
  649. /****************************************************************************/
  650.  
  651. template <class Element>
  652. inline KPComparableList<Element>::~KPComparableList()
  653. { /* do nothing new. */ }
  654.  
  655. /****************************************************************************/
  656.  
  657. template <class Element>
  658. inline KPComparableList<Element> &
  659. KPComparableList<Element>::operator=(const KPList<Element> &list)
  660. {
  661.     KPList<Element>::operator=(list);
  662.     return *this;
  663. }
  664.  
  665. /****************************************************************************/
  666.  
  667. template <class Element>
  668. inline KPComparableList<Element> &
  669. KPComparableList<Element>::operator=(const Element &element)
  670. {
  671.     KPList<Element>::operator=(element);
  672.     return *this;
  673. }
  674.  
  675. /****************************************************************************/
  676.  
  677. template <class Element>
  678. inline KPComparableList<Element>
  679. KPComparableList<Element>::operator+(const KPList<Element> &list)
  680. {
  681.     KPComparableList<Element> new_list(*this);
  682.     new_list += list;
  683.     return new_list;
  684. }
  685.  
  686. /****************************************************************************/
  687.  
  688. template <class Element>
  689. inline KPComparableList<Element>
  690. KPComparableList<Element>::operator+(const Element &element)
  691. {
  692.     KPComparableList<Element> new_list(*this);
  693.     new_list += element;
  694.     return new_list;
  695. }
  696.  
  697. /****************************************************************************/
  698.  
  699. template <class Element>
  700. inline KPComparableList<Element>
  701. KPComparableList<Element>::operator-(const KPComparableList<Element> &list)
  702. {
  703.     KPComparableList<Element> new_list(*this);
  704.     new_list -= list;
  705.     return new_list;
  706. }
  707.  
  708. /****************************************************************************/
  709.  
  710. template <class Element>
  711. inline KPComparableList<Element>
  712. KPComparableList<Element>::operator-(const Element &element)
  713. {
  714.     KPComparableList<Element> new_list(*this);
  715.     new_list -= element;
  716.     return new_list;
  717. }
  718.  
  719. /****************************************************************************/
  720.  
  721. template <class Element>
  722. void
  723. KPComparableList<Element>::operator-=(const KPComparableList<Element> &list)
  724. {
  725.     for (register const Node *node = list.my_head; node; node = node->next)
  726.         *this -= node->element;
  727. }
  728.  
  729. /****************************************************************************/
  730.  
  731. template <class Element>
  732. void
  733. KPComparableList<Element>::operator-=(const Element &element)
  734. {
  735.     if (my_iterator_count > 0)
  736.         error("operator-=() - cannot remove elements, iterators present");
  737.  
  738.     for (register Node *node = my_tail; node; node = node->previous)
  739.         if (node->element == element) {
  740.             if (node->previous)
  741.                 node->previous->next = node->next;
  742.             else
  743.                 my_head = node->next;
  744.             if (node->next)
  745.                 node->next->previous = node->previous;
  746.             else
  747.                 my_tail = node->previous;
  748.             delete node;
  749.             my_size--;
  750.             break;
  751.         }
  752. }
  753.  
  754. /****************************************************************************/
  755.  
  756. template <class Element>
  757. bool
  758. KPComparableList<Element>::operator==(const KPComparableList<Element> &list)
  759.                                                                         const
  760. {
  761.     if (this == &list)
  762.         return true;
  763.     
  764.     if (my_size != list.my_size)
  765.         return false;
  766.  
  767.     register const Node *node1, *node2;
  768.     for (node1 = my_head, node2 = list.my_head; node1;
  769.                                     node1 = node1->next, node2 = node2->next)
  770.         if (!(node1->element == node2->element))
  771.             return false;
  772.     
  773.     return true;
  774. }
  775.  
  776. /****************************************************************************/
  777.  
  778. template <class Element>
  779. inline bool
  780. KPComparableList<Element>::operator!=(const KPComparableList<Element> &list)
  781.                                                                         const
  782. {
  783.     return !(*this == list);
  784. }
  785.  
  786. /****************************************************************************/
  787.  
  788. template <class Element>
  789. bool
  790. KPComparableList<Element>::contains(const KPComparableList<Element> &list) const
  791. {
  792.     for (register const Node *node = list.my_head; node; node = node->next)
  793.         if (!contains(node->element))
  794.             return false;
  795.  
  796.     return true;
  797. }
  798.  
  799. /****************************************************************************/
  800.  
  801. template <class Element>
  802. bool
  803. KPComparableList<Element>::contains(const Element &element) const
  804. {
  805.     for (register const Node *node = my_head; node; node = node->next)
  806.         if (node->element == element)
  807.             return true;
  808.  
  809.     return false;
  810. }
  811.  
  812. /****************************************************************************/
  813.  
  814. template <class Element>
  815. int
  816. KPComparableList<Element>::occurrences_of(const Element &element) const
  817. {
  818.     int occurrences = 0;
  819.  
  820.     for (register const Node *node = my_head; node; node = node->next)
  821.         if (node->element == element)
  822.             occurrences++;
  823.  
  824.     return occurrences;
  825. }
  826.  
  827. /****************************************************************************/
  828.  
  829. // I don't know why I have to redeclare clear() here.  I think it's another
  830. // one of those infamous g++ bugs.
  831.  
  832. template <class Element>
  833. void
  834. KPComparableList<Element>::clear()
  835. {
  836.     KPList<Element>::clear();
  837. }
  838.  
  839. /****************************************************************************/
  840.  
  841. template <class Element>
  842. void
  843. KPComparableList<Element>::clear(const Element &element)
  844. {
  845.     register Node *prevnode;
  846.  
  847.     if (my_iterator_count > 0)
  848.         error("clear() - cannot remove elements, iterators present");
  849.  
  850.     for (register Node *node = my_tail; node; node = prevnode) {
  851.         prevnode = node->previous;
  852.         if (node->element == element) {
  853.             if (node->previous)
  854.                 node->previous->next = node->next;
  855.             else
  856.                 my_head = node->next;
  857.             if (node->next)
  858.                 node->next->previous = node->previous;
  859.             else
  860.                 my_tail = node->previous;
  861.             delete node;
  862.             my_size--;
  863.         }
  864.     }
  865. }
  866.  
  867. /****************************************************************************/
  868.  
  869. template <class Element>
  870. void
  871. KPComparableList<Element>::clear(const KPComparableList<Element> &list)
  872. {
  873.     if (my_iterator_count > 0)
  874.         error("clear() - cannot remove elements, iterators present");
  875.  
  876.     for (register Node *node = list.my_head; node; node = node->next)
  877.         clear(node->element);
  878. }
  879.  
  880. /****************************************************************************/
  881.  
  882. template <class Element>
  883. -1, elementlist);
  884.  
  885.     delete [] elementlist;
  886. }
  887.  
  888. /****************************************************************************/
  889.  
  890. template <class Element>
  891. Element &
  892. KPSortableList<Element>::min()
  893. {
  894.     if (my_size < 1)
  895.         error("min() - empty list");
  896.  
  897.     register Element *min = &my_head->element;
  898.     for (register Node *node = my_head->next; node; node = node->next)
  899.         if (node->element < *min)
  900.             min = &node->element;
  901.  
  902.     return *min;
  903. }
  904.  
  905. /****************************************************************************/
  906.  
  907. template <class Element>
  908. const Element &
  909. KPSortableList<Element>::min() const
  910. {
  911.     if (my_size < 1)
  912.         error("min() - empty list");
  913.  
  914.     register const Element *min = &my_head->element;
  915.     for (register const Node *node = my_head->next; node; node = node->next)
  916.         if (node->element < *min)
  917.             min = &node->element;
  918.  
  919.     return *min;
  920. }
  921.  
  922. /****************************************************************************/
  923.  
  924. template <class Element>
  925. Element &
  926. KPSortableList<Element>::max()
  927. {
  928.     if (my_size < 1)
  929.         error("max() - empty list");
  930.  
  931.     register Element *max = &my_head->element;
  932.     for (register Node *node = my_head->next; node; node = node->next)
  933.         if (*max < node->element)
  934.             max = &node->element;
  935.  
  936.     return *max;
  937. }
  938.  
  939. /****************************************************************************/
  940.  
  941. template <class Element>
  942. const Element &
  943. KPSortableList<Element>::max() const
  944. {
  945.     if (my_size < 1)
  946.         error("max() - empty list");
  947.  
  948.     register const Element *max = &my_head->element;
  949.     for (register const Node *node = my_head->next; node; node = node->next)
  950.         if (*max < node->element)
  951.             max = &node->element;
  952.  
  953.     return *max;
  954. }
  955.  
  956. /****************************************************************************/
  957.  
  958. template <class Element>
  959. void
  960. KPSortableList<Element>::error(const char *msg)
  961. {
  962.     cerr << "KPSortableList: " << msg << '\n';
  963.     exit(EXIT_FAILURE);
  964. }
  965.  
  966. /****************************************************************************/
  967.  
  968. template <class Element>
  969. inline
  970. KPReadOnlyIterator<Element>::KPReadOnlyIterator()
  971. {
  972.     my_list = NULL;
  973.     my_current = NULL;
  974. }
  975.  
  976. /****************************************************************************/
  977.  
  978. template <class Element>
  979. inline
  980. KPReadOnlyIterator<Element>::KPReadOnlyIterator(const KPList<Element> &list)
  981. {
  982.     my_list = &list;
  983.     // Even though list is a const, update its iterator count.
  984.     ((KPList<Element> &)list).my_iterator_count++;
  985.     my_current = list.my_head;
  986. }
  987.  
  988. /****************************************************************************/
  989.  
  990. template <class Element>
  991. inline
  992. KPReadOnlyIterator<Element>::KPReadOnlyIterator(
  993.                                 const KPReadOnlyIterator<Element> &iterator)
  994.                                             : my_list(iterator.my_list)
  995. {
  996.     if (my_list)
  997.         ((KPList<Element> *)my_list)->my_iterator_count++;
  998.     my_current = iterator.my_current;
  999. }
  1000.  
  1001. /****************************************************************************/
  1002.  
  1003. template <class Element>
  1004. inline
  1005. KPReadOnlyIterator<Element>::~KPReadOnlyIterator()
  1006. {
  1007.     if (my_list)
  1008.         ((KPList<Element> *)my_list)->my_iterator_count--;
  1009. }
  1010.  
  1011. /****************************************************************************/
  1012.  
  1013. template <class Element>
  1014. inline KPReadOnlyIterator<Element> &
  1015. KPReadOnlyIterator<Element>::iterate_over(const KPList<Element> &list)
  1016. {
  1017.     if (my_list)
  1018.         ((KPList<Element> *)my_list)->my_iterator_count--;
  1019.     my_list = &list;
  1020.     ((KPList<Element> *)my_list)->my_iterator_count++;
  1021.     my_current = my_list->my_head;
  1022.  
  1023.     return *this;
  1024. }
  1025.  
  1026. /****************************************************************************/
  1027.  
  1028. template <class Element>
  1029. inline KPReadOnlyIterator<Element> &
  1030. KPReadOnlyIterator<Element>::iterate_over()
  1031. {
  1032.     if (my_list) {
  1033.         ((KPList<Element> *)my_list)->my_iterator_count--;
  1034.         my_list = NULL;
  1035.         my_current = NULL;
  1036.     }
  1037.  
  1038.     return *this;
  1039. }
  1040.  
  1041. /****************************************************************************/
  1042.  
  1043.  
  1044. template <class Element>
  1045. inline KPReadOnlyIterator<Element> &
  1046. KPReadOnlyIterator<Element>::operator=(const KPReadOnlyIterator<Element>
  1047.                                                                     &iterator)
  1048. {
  1049.     if (my_list)
  1050.         ((KPList<Element> *)my_list)->my_iterator_count--;
  1051.     my_list = iterator.my_list;
  1052.     if (my_list)
  1053.         ((KPList<Element> *)my_list)->my_iterator_count++;
  1054.     my_current = iterator.my_current;
  1055.  
  1056.     return *this;
  1057. }
  1058.  
  1059. /****************************************************************************/
  1060.  
  1061. template <class Element>
  1062. inline const Element &
  1063. KPReadOnlyIterator<Element>::current() const
  1064. {
  1065.     if(!my_current)
  1066.         error("current() - no current element");
  1067.     return my_current->element;
  1068. }
  1069.  
  1070.  
  1071. /****************************************************************************/
  1072.  
  1073. template <class Element>
  1074. inline const Element *
  1075. KPReadOnlyIterator<Element>::ptr() const
  1076. {
  1077.     if (my_current)
  1078.         return &my_current->element;
  1079.     else
  1080.         return NULL;
  1081. }
  1082.  
  1083. /****************************************************************************/
  1084.  
  1085. template <class Element>
  1086. inline KPReadOnlyIterator<Element> &
  1087. KPReadOnlyIterator<Element>::beginning()
  1088. {
  1089.     if (my_list)
  1090.         my_current = my_list->my_head;
  1091.     return *this;
  1092. }
  1093.  
  1094. /****************************************************************************/
  1095.  
  1096. template <class Element>
  1097. inline KPReadOnlyIterator<Element> &
  1098. KPReadOnlyIterator<Element>::end()
  1099. {
  1100.     if (my_list)
  1101.         my_current = my_list->my_tail;
  1102.     return *this;
  1103. }
  1104.  
  1105. /****************************************************************************/
  1106.  
  1107. template <class Element>
  1108. inline KPReadOnlyIterator<Element> &
  1109. KPReadOnlyIterator<Element>::operator++()  // Prefix
  1110. {
  1111.     if (!my_current)
  1112.         error("operator++() - no next element");
  1113.  
  1114.     my_current = my_current->next;
  1115.     return *this;
  1116. }
  1117.  
  1118. /****************************************************************************/
  1119.  
  1120. template <class Element>
  1121. inline KPReadOnlyIterator<Element> &
  1122. KPReadOnlyIterator<Element>::operator--()  // Prefix
  1123. {
  1124.     if (!my_current)
  1125.         error("operator--() - no previous element");
  1126.  
  1127.     my_current = my_current->previous;
  1128.     return *this;
  1129. }
  1130.  
  1131. /****************************************************************************/
  1132.  
  1133. template <class Element>
  1134. inline void
  1135. KPReadOnlyIterator<Element>::operator++(int)  // Postfix
  1136. {
  1137.     if (!my_current)
  1138.         error("operator++() - no next element");
  1139.  
  1140.     my_current = my_current->next;
  1141. }
  1142.  
  1143. /****************************************************************************/
  1144.  
  1145. template <class Element>
  1146. inline void
  1147. KPReadOnlyIterator<Element>::operator--(int)  // Postfix
  1148. {
  1149.     if (!my_current)
  1150.         error("operator--() - no previous element");
  1151.  
  1152.     my_current = my_current->previous;
  1153. }
  1154.  
  1155. /****************************************************************************/
  1156.  
  1157. template <class Element>
  1158. inline const Element &
  1159. KPReadOnlyIterator<Element>::operator*() const
  1160. {
  1161.     if (!my_current)
  1162.         error("operator*() - no current element");
  1163.  
  1164.     return my_current->element;
  1165. }
  1166.  
  1167. /****************************************************************************/
  1168.  
  1169. template <class Element>
  1170. inline const Element *
  1171. KPReadOnlyIterator<Element>::operator->() const
  1172. {
  1173.     if (!my_current)
  1174.         error("operator->() - no current element");
  1175.  
  1176.     return &my_current->element;
  1177. }
  1178.  
  1179. /****************************************************************************/
  1180.  
  1181. template <class Element>
  1182. inline bool
  1183. KPReadOnlyIterator<Element>::at_beginning() const
  1184. {
  1185.     return (my_current && !my_current->previous);
  1186. }
  1187.  
  1188. /****************************************************************************/
  1189.  
  1190. template <class Element>
  1191. inline bool
  1192. KPReadOnlyIterator<Element>::at_end() const
  1193. {
  1194.     return (my_current && !my_current->next);
  1195. }
  1196.  
  1197. /****************************************************************************/
  1198.  
  1199. template <class Element>
  1200. inline int
  1201. KPReadOnlyIterator<Element>::size() const
  1202. {
  1203.     return my_list->size();
  1204. }
  1205.  
  1206. /****************************************************************************/
  1207.  
  1208. template <class Element>
  1209. inline bool
  1210. KPReadOnlyIterator<Element>::is_empty() const
  1211. {
  1212.     return my_list->is_empty();
  1213. }
  1214.  
  1215. /****************************************************************************/
  1216.  
  1217. template <class Element>
  1218. inline const KPList<Element> &
  1219. KPReadOnlyIterator<Element>::list() const
  1220. {
  1221.     if (!my_list)
  1222.         error("list() - no list associated with iterator");
  1223.  
  1224.     return *my_list;
  1225. }
  1226.  
  1227. /****************************************************************************/
  1228.  
  1229. template <class Element>
  1230. void
  1231. KPReadOnlyIterator<Element>::error(const char *msg)
  1232. {
  1233.     cerr << "KPReadOnlyIterator: " << msg << '\n';
  1234.     exit(EXIT_FAILURE);
  1235. }
  1236.  
  1237. /****************************************************************************/
  1238.  
  1239. template <class Element>
  1240. inline
  1241. KPIterator<Element>::KPIterator()
  1242. {
  1243.     my_list = NULL;
  1244.     my_current = NULL;
  1245. }
  1246.  
  1247. /****************************************************************************/
  1248.  
  1249. template <class Element>
  1250. inline
  1251. KPIterator<Element>::KPIterator(KPList<Element> &list)
  1252. {
  1253.     my_list = &list;
  1254.     list.my_iterator_count++;
  1255.     my_current = list.my_head;
  1256. }
  1257.  
  1258. /****************************************************************************/
  1259.  
  1260. template <class Element>
  1261. inline
  1262. KPIterator<Element>::KPIterator(const KPIterator<Element> &iterator)
  1263.                                                 : my_list(iterator.my_list)
  1264. {
  1265.     if (my_list)
  1266.         my_list->my_iterator_count++;
  1267.     my_current = iterator.my_current;
  1268. }
  1269.  
  1270. /****************************************************************************/
  1271.  
  1272. template <class Element>
  1273. inline
  1274. KPIterator<Element>::~KPIterator()
  1275. {
  1276.     if (my_list)
  1277.         my_list->my_iterator_count--;
  1278. }
  1279.  
  1280. /****************************************************************************/
  1281.  
  1282. template <class Element>
  1283. inline KPIterator<Element> &
  1284. KPIterator<Element>::iterate_over(KPList<Element> &list)
  1285. {
  1286.     if (my_list)
  1287.         my_list->my_iterator_count--;
  1288.     my_list = &list;
  1289.     my_list->my_iterator_count++;
  1290.     my_current = my_list->my_head;
  1291.  
  1292.     return *this;
  1293. }
  1294.  
  1295. /****************************************************************************/
  1296.  
  1297. template <class Element>
  1298. inline KPIterator<Element> &
  1299. KPIterator<Element>::iterate_over()
  1300. {
  1301.     if (my_list) {
  1302.         my_list->my_iterator_count--;
  1303.         my_list = NULL;
  1304.         my_current = NULL;
  1305.     }
  1306.  
  1307.     return *this;
  1308. }
  1309.  
  1310. /****************************************************************************/
  1311.  
  1312.  
  1313. template <class Element>
  1314. inline KPIterator<Element> &
  1315. KPIterator<Element>::operator=(const KPIterator<Element> &iterator)
  1316. {
  1317.     if (my_list)
  1318.         my_list->my_iterator_count--;
  1319.     my_list = iterator.my_list;
  1320.     if (my_list)
  1321.         my_list->my_iterator_count++;
  1322.     my_current = iterator.my_current;
  1323.  
  1324.     return *this;
  1325. }
  1326.  
  1327. /****************************************************************************/
  1328.  
  1329. template <class Element>
  1330. KPIterator<Element> &
  1331. KPIterator<Element>::insert_before_current(const Element &element)
  1332. {
  1333.     if (!my_current)
  1334.         error("insert_before_current() - no current element");
  1335.  
  1336.     KPList<Element>::Node *newnode = new KPList<Element>::Node;
  1337.     check_mem(newnode);
  1338.     newnode->element = element;
  1339.  
  1340.     if (my_current->previous) {
  1341.         if (my_current == &my_deleted) {
  1342.             newnode->previous = my_current->previous;
  1343.             newnode->next = my_current->next;
  1344.             my_current->previous->next = newnode;
  1345.             if (my_current->next)
  1346.                 my_current->next->previous = newnode;
  1347.             else
  1348.                 my_list->my_tail = newnode;
  1349.             my_current->previous = newnode;
  1350.         }
  1351.         else {
  1352.             newnode->previous = my_current->previous;
  1353.             newnode->next = my_current;
  1354.             my_current->previous->next = newnode;
  1355.             my_current->previous = newnode;
  1356.         }
  1357.     }
  1358.     else {
  1359.         my_list->my_head->previous = newnode;
  1360.         my_current->previous = newnode; // in case my_current == my_deleted
  1361.         newnode->next = my_list->my_head;
  1362.         newnode->previous = NULL;
  1363.         my_list->my_head = newnode;
  1364.     }
  1365.  
  1366.     my_list->my_size++;
  1367.     return *this;
  1368. }
  1369.  
  1370. /****************************************************************************/
  1371.  
  1372. template <class Element>
  1373. KPIterator<Element> &
  1374. KPIterator<Element>::insert_after_current(const Element &element)
  1375. {
  1376.     if (!my_current)
  1377.         error("insert_after_current() - no current element");
  1378.     
  1379.     KPList<Element>::Node *newnode = new KPList<Element>::Node;
  1380.     check_mem(newnode);
  1381.     newnode->element = element;
  1382.  
  1383.     if (my_current->next) {
  1384.         if (my_current == &my_deleted) {
  1385.             newnode->next = my_current->next;
  1386.             newnode->previous = my_current->previous;
  1387.             my_current->next->previous = newnode;
  1388.             if (my_current->previous)
  1389.                 my_current->previous->next = newnode;
  1390.             else
  1391.                 my_list->my_head = newnode;
  1392.             my_current->next = newnode;
  1393.         }
  1394.         else {
  1395.             newnode->next = my_current->next;
  1396.             newnode->previous = my_current;
  1397.             my_current->next->previous = newnode;
  1398.             my_current->next = newnode;
  1399.         }
  1400.     }
  1401.     else {
  1402.         my_list->my_tail->next = newnode;
  1403.         my_current->next = newnode;  // in case my_current == my_deleted
  1404.         newnode->previous = my_list->my_tail;
  1405.         newnode->next = NULL;
  1406.         my_list->my_tail = newnode;
  1407.     }
  1408.  
  1409.     my_list->my_size++;
  1410.     return *this;
  1411. }
  1412.  
  1413. /****************************************************************************/
  1414.  
  1415. template <class Element>
  1416. KPIterator<Element> &
  1417. KPIterator<Element>::replace_current_with(const Element &element)
  1418. {
  1419.     if (!my_current)
  1420.         error("replace_current_with() - no current element");
  1421.     if (my_current == &my_deleted)
  1422.         error("replace_current_with() - current element has been deleted");
  1423.     my_current->element = element;
  1424.  
  1425.     return *this;
  1426. }
  1427.  
  1428. /****************************************************************************/
  1429.  
  1430. template <class Element>
  1431. inline Element &
  1432. KPIterator<Element>::current()
  1433. {
  1434.     if(!my_current)
  1435.         error("current() - no current element");
  1436.     return my_current->element;
  1437. }
  1438.  
  1439.  
  1440. /****************************************************************************/
  1441.  
  1442. template <class Element>
  1443. inline Element *
  1444. KPIterator<Element>::ptr()
  1445. {
  1446.     if (my_current)
  1447.         return &my_current->element;
  1448.     else
  1449.         return NULL;
  1450. }
  1451.  
  1452. /****************************************************************************/
  1453.  
  1454. template <class Element>
  1455. void
  1456. KPIterator<Element>::remove_current()
  1457. {
  1458.     if (!my_current)
  1459.         error("remove_current() - no current element");
  1460.  
  1461.     else if (my_current == &my_deleted)
  1462.         error("remove_current() - current element has already been removed");
  1463.  
  1464.     else if (my_list->my_iterator_count > 1)
  1465.         error("remove_current() - cannot remove element, "
  1466.               "more than one iterator");
  1467.  
  1468.     else {
  1469.         my_deleted.previous = my_current->previous;
  1470.         my_deleted.next = my_current->next;
  1471.         delete my_current;
  1472.         my_current = &my_deleted;
  1473.  
  1474.         if (my_deleted.previous)
  1475.             my_deleted.previous->next = my_deleted.next;
  1476.         else
  1477.             my_list->my_head = my_deleted.next;
  1478.  
  1479.         if (my_deleted.next)
  1480.             my_deleted.next->previous = my_deleted.previous;
  1481.         else
  1482.             my_list->my_tail = my_deleted.previous;
  1483.  
  1484.         my_list->my_size--;
  1485.     }
  1486. }
  1487.  
  1488. /****************************************************************************/
  1489.  
  1490. template <class Element>
  1491. inline KPIterator<Element> &
  1492. KPIterator<Element>::beginning()
  1493. {
  1494.     if (my_list)
  1495.         my_current = my_list->my_head;
  1496.     return *this;
  1497. }
  1498.  
  1499. /****************************************************************************/
  1500.  
  1501. template <class Element>
  1502. inline KPIterator<Element> &
  1503. KPIterator<Element>::end()
  1504. {
  1505.     if (my_list)
  1506.         my_current = my_list->my_tail;
  1507.     return *this;
  1508. }
  1509.  
  1510. /****************************************************************************/
  1511.  
  1512. template <class Element>
  1513. inline KPIterator<Element> &
  1514. KPIterator<Element>::operator++()  // Prefix
  1515. {
  1516.     if (!my_current)
  1517.         error("operator++() - no next element");
  1518.  
  1519.     my_current = my_current->next;
  1520.     return *this;
  1521. }
  1522.  
  1523. /****************************************************************************/
  1524.  
  1525. template <class Element>
  1526. inline KPIterator<Element> &
  1527. KPIterator<Element>::operator--()  // Prefix
  1528. {
  1529.     if (!my_current)
  1530.         error("operator--() - no previous element");
  1531.  
  1532.     my_current = my_current->previous;
  1533.     return *this;
  1534. }
  1535.  
  1536. /****************************************************************************/
  1537.  
  1538. template <class Element>
  1539. inline void
  1540. KPIterator<Element>::operator++(int)  // Postfix
  1541. {
  1542.     if (!my_current)
  1543.         error("operator++() - no next element");
  1544.  
  1545.     my_current = my_current->next;
  1546. }
  1547.  
  1548. /****************************************************************************/
  1549.  
  1550. template <class Element>
  1551. inline void
  1552. KPIterator<Element>::operator--(int)  // Postfix
  1553. {
  1554.     if (!my_current)
  1555.         error("operator--() - no previous element");
  1556.  
  1557.     my_current = my_current->previous;
  1558. }
  1559.  
  1560. /****************************************************************************/
  1561.  
  1562. template <class Element>
  1563. inline Element &
  1564. KPIterator<Element>::operator*()
  1565. {
  1566.     if (!my_current)
  1567.         error("operator*() - no current element");
  1568.  
  1569.     return my_current->element;
  1570. }
  1571.  
  1572. /****************************************************************************/
  1573.  
  1574. template <class Element>
  1575. inline Element *
  1576. KPIterator<Element>::operator->()
  1577. {
  1578.     if (!my_current)
  1579.         error("operator->() - no current element");
  1580.  
  1581.     return &my_current->element;
  1582. }
  1583.  
  1584. /****************************************************************************/
  1585.  
  1586. template <class Element>
  1587. inline bool
  1588. KPIterator<Element>::at_beginning() const
  1589. {
  1590.     return (my_current && !my_current->previous);
  1591. }
  1592.  
  1593. /****************************************************************************/
  1594.  
  1595. template <class Element>
  1596. inline bool
  1597. KPIterator<Element>::at_end() const
  1598. {
  1599.     return (my_current && !my_current->next);
  1600. }
  1601.  
  1602. /****************************************************************************/
  1603.  
  1604. template <class Element>
  1605. inline int
  1606. KPIterator<Element>::size() const
  1607. {
  1608.     return my_list->size();
  1609. }
  1610.  
  1611. /****************************************************************************/
  1612.  
  1613. template <class Element>
  1614. inline bool
  1615. KPIterator<Element>::is_empty() const
  1616. {
  1617.     return my_list->is_empty();
  1618. }
  1619.  
  1620. /****************************************************************************/
  1621.  
  1622. template <class Element>
  1623. inline KPList<Element> &
  1624. KPIterator<Element>::list()
  1625. {
  1626.     if (!my_list)
  1627.         error("list() - no list associated with iterator");
  1628.  
  1629.     return *my_list;
  1630. }
  1631.  
  1632. /****************************************************************************/
  1633.  
  1634. template <class Element>
  1635. void
  1636. KPIterator<Element>::error(const char *msg)
  1637. {
  1638.     cerr << "KPIterator: " << msg << '\n';
  1639.     exit(EXIT_FAILURE);
  1640. }
  1641.  
  1642. /****************************************************************************/
  1643.  
  1644. #endif /* KP_LIST_DEFINED */
  1645.